home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Dots & Pixels
/
sources
/
flowsettings.cp
< prev
next >
Wrap
Text File
|
1995-09-29
|
9KB
|
320 lines
#include <assert.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <iostream.h>
#include "streamutils.h"
#include "flowsettings.h"
ostream& operator<<( ostream& destroom, const flowsettings &thesettings)
{
char possible_semicolon[ 2] = {0, 0};
destroom << '[';
if( !thesettings.is_translation_free())
{
destroom << possible_semicolon
<< "trans = (" << thesettings.translation_x
<< ',' << thesettings.translation_y << ')';
possible_semicolon[ 0] = ';';
}
if( !thesettings.is_expansion_free())
{
destroom << possible_semicolon << "exp = " << thesettings.expansion;
possible_semicolon[ 0] = ';';
}
if( !thesettings.is_rotation_free())
{
destroom << possible_semicolon << "rot = " << thesettings.rotation;
possible_semicolon[ 0] = ';';
}
if( !thesettings.is_shear_free())
{
destroom << possible_semicolon
<< "shear = (" << thesettings.shear_magnitude
<< ',' << thesettings.shear_direction << ')';
possible_semicolon[ 0] = ';';
}
return destroom << ']';
}
istream &operator>>( istream &destroom, flowsettings &thesettings)
{
thesettings.init(); // give non-specified values standard value
char nextletter;
destroom >> nextletter; // skips whitespace and newlines
int go_on = (nextletter == '[');
//
// 950208: also accept capital letters as input, and accept alternate forms:
// x/X for horizontal translation
// y/Y for vertical translation
// m/M for shear magnitude
// d/D for shear direction
// Note: a problem might occur here, since 'd' also could mean divergence
//
while( go_on)
{
nextletter = skip_spaces( destroom); // don't skip newlines
switch( nextletter)
{
case 't': // trans
case 'T':
skip_till_numberstart( destroom);
destroom >> thesettings.translation_x;
destroom >> nextletter; assert( nextletter == ',');
destroom >> thesettings.translation_y;
destroom >> nextletter; assert( nextletter == ')');
break;
case 'x': // horizontal translation (alternate format)
case 'X':
skip_till_numberstart( destroom);
destroom >> thesettings.translation_x;
break;
case 'y': // vertical translation (alternate format)
case 'Y':
skip_till_numberstart( destroom);
destroom >> thesettings.translation_y;
break;
case 'e': // exp
case 'E':
skip_till_numberstart( destroom);
destroom >> thesettings.expansion;
break;
case 'r': // rot
case 'R':
skip_till_numberstart( destroom);
destroom >> thesettings.rotation;
break;
case 's': // shear
case 'S':
skip_till_numberstart( destroom);
destroom >> thesettings.shear_magnitude;
destroom >> nextletter; assert( nextletter == ',');
destroom >> thesettings.shear_direction;
destroom >> nextletter; assert( nextletter == ')');
break;
case 'm': // shear magnitude (alternate format)
case 'M':
skip_till_numberstart( destroom);
destroom >> thesettings.shear_magnitude;
break;
case 'd': // shear direction (alternate format)
case 'D':
skip_till_numberstart( destroom);
destroom >> thesettings.shear_direction;
break;
case ';':
//
// simply skip this one.
//
break;
case ']':
go_on = false;
break;
default:
destroom.putback( nextletter);
(void)destroom.setf( ios::failbit);
go_on = false;
break;
}
}
return destroom;
}
int flowsettings::operator==( const flowsettings &that) const
{
return
(translation_x == that.translation_x) &&
(translation_y == that.translation_y) &&
(expansion == that.expansion) &&
(rotation == that.rotation) &&
(shear_magnitude == that.shear_magnitude) &&
(shear_direction == that.shear_direction);
}
ostream& operator<<( ostream& destroom, const flowexpsettings &thesettings)
{
if( thesettings.point_zero == (const flowsettings &)thesettings)
{
return destroom << (flowsettings &)thesettings
<< '>' << thesettings.point_one;
} else {
return destroom << (flowsettings &)thesettings << '>'
<< thesettings.point_zero << '-' << thesettings.point_one;
}
}
istream &operator>>( istream &destroom, flowexpsettings &thesettings)
{
destroom >> (flowsettings &)thesettings;
char nextletter;
destroom >> nextletter; // might be a newline
if( nextletter == '>')
{
destroom >> thesettings.point_zero;
destroom >> nextletter;
if( nextletter == '-')
{
destroom >> thesettings.point_one;
} else {
thesettings.point_one = thesettings.point_zero;
thesettings.point_zero = (flowsettings &)thesettings;
destroom.putback( nextletter);
}
} else {
thesettings.point_zero.init();
thesettings.point_one.init();
destroom.putback( nextletter);
(void)destroom.setf( ios::failbit);
}
return destroom;
}
void flowexpsettings::shorthand_out( ostream &destroom, int force_three) const
{
//
// We start by giving the reference flow:
//
const char marker[] = "xyermd"; // mnemonic for dx, dy, exp, rot, mag, dir
destroom << marker << '\t'
<< translation_x << '\t'
<< translation_y << '\t'
<< expansion << '\t'
<< rotation << '\t'
<< shear_magnitude << '\t'
<< shear_direction;
if( (!force_three) && (point_zero == *(const flowsettings *)this))
{
#define dump_if_different( fieldName, prefix) \
if( fieldName != point_one.fieldName) \
{ \
destroom << prefix << point_one.fieldName; \
}
dump_if_different( translation_x , "\tx\t");
dump_if_different( translation_y , "\ty\t");
dump_if_different( expansion , "\te\t");
dump_if_different( rotation , "\tr\t");
dump_if_different( shear_magnitude, "\tm\t");
dump_if_different( shear_direction, "\td\t");
#undef dump_if_different
} else {
#define dump_if_different( fieldName, prefix) \
if( (fieldName != point_one.fieldName) \
|| (fieldName != point_zero.fieldName)) \
{ \
destroom << prefix << point_zero.fieldName \
<< '\t' << point_one.fieldName; \
}
dump_if_different( translation_x , "\tx\t");
dump_if_different( translation_y , "\ty\t");
dump_if_different( expansion , "\te\t");
dump_if_different( rotation , "\tr\t");
dump_if_different( shear_magnitude, "\tm\t");
dump_if_different( shear_direction, "\td\t");
#undef dump_if_different
}
destroom << '\t' << marker;
}
void flowexpsettings::longhand_out( ostream &destroom, int force_three) const
{
//
// We start by giving the reference flow:
//
const char marker[] = "xyermd";
destroom << marker << '\t'
<< translation_x << '\t'
<< translation_y << '\t'
<< expansion << '\t'
<< rotation << '\t'
<< shear_magnitude << '\t'
<< shear_direction;
if( (!force_three) && (point_zero == *(const flowsettings *)this))
{
#define dump_anyway( fieldName, prefix) \
destroom << prefix << point_one.fieldName;
dump_anyway( translation_x , "\tx\t");
dump_anyway( translation_y , "\ty\t");
dump_anyway( expansion , "\te\t");
dump_anyway( rotation , "\tr\t");
dump_anyway( shear_magnitude, "\tm\t");
dump_anyway( shear_direction, "\td\t");
#undef dump_anyway
} else {
#define dump_anyway( fieldName, prefix) \
destroom << prefix << point_zero.fieldName \
<< '\t' << point_one.fieldName;
dump_anyway( translation_x , "\tx\t");
dump_anyway( translation_y , "\ty\t");
dump_anyway( expansion , "\te\t");
dump_anyway( rotation , "\tr\t");
dump_anyway( shear_magnitude, "\tm\t");
dump_anyway( shear_direction, "\td\t");
#undef dump_anyway
}
destroom << '\t' << marker;
}
void flowexpsettings::getvalue( flowsettings *new_value, const double lambda)
{
//
// Note: exp and mag are logarithmical quantities
//
new_value->translation_x = lin_interpolate(
point_zero.translation_x, point_one.translation_x, lambda);
new_value->translation_y = lin_interpolate(
point_zero.translation_y, point_one.translation_y, lambda);
new_value->expansion =
log_interpolate( point_zero.expansion, point_one.expansion, lambda);
new_value->rotation =
lin_interpolate( point_zero.rotation, point_one.rotation, lambda);
new_value->shear_magnitude = log_interpolate(
point_zero.shear_magnitude, point_one.shear_magnitude, lambda);
new_value->shear_direction = lin_interpolate(
point_zero.shear_direction, point_one.shear_direction, lambda);
}
int flowexpsettings::translation_does_change() const
{
return (dx_does_change() || dy_does_change());
}
int flowexpsettings::shear_does_change() const
{
return (mag_does_change() || dir_does_change());
}